use crate::neural::NeuralNetwork;
use crate::symbolic::{Fact, Rule, SymbolicEngine};
use crate::transformer::Transformer;
use std::collections::HashMap;

/// 神经符号AI系统 - 整合神经网络和符号推理
pub struct NeuroSymbolicSystem {
    neural: NeuralNetwork,
    symbolic: SymbolicEngine,
    transformer: Option<Transformer>,
    /// 神经输出到符号概念的映射
    neural_to_symbolic: HashMap<usize, String>,
    /// 符号推理的置信度阈值
    confidence_threshold: f64,
}

impl NeuroSymbolicSystem {
    /// 创建新的神经符号系统
    pub fn new(neural: NeuralNetwork, symbolic: SymbolicEngine) -> Self {
        NeuroSymbolicSystem {
            neural,
            symbolic,
            transformer: None,
            neural_to_symbolic: HashMap::new(),
            confidence_threshold: 0.5,
        }
    }

    /// 创建带Transformer的神经符号系统
    pub fn with_transformer(
        neural: NeuralNetwork,
        symbolic: SymbolicEngine,
        transformer: Transformer,
    ) -> Self {
        NeuroSymbolicSystem {
            neural,
            symbolic,
            transformer: Some(transformer),
            neural_to_symbolic: HashMap::new(),
            confidence_threshold: 0.5,
        }
    }

    /// 设置神经输出到符号的映射
    pub fn set_neural_mapping(&mut self, output_index: usize, concept: String) {
        self.neural_to_symbolic.insert(output_index, concept);
    }

    /// 设置置信度阈值
    pub fn set_confidence_threshold(&mut self, threshold: f64) {
        self.confidence_threshold = threshold.clamp(0.0, 1.0);
    }

    /// 神经感知 -> 符号提取
    /// 将神经网络的输出转换为符号事实
    pub fn perceive(&mut self, inputs: &[f64]) -> Vec<Fact> {
        // 神经网络前向传播
        let outputs = self.neural.predict(inputs);

        // 将神经输出转换为符号事实
        let mut facts = Vec::new();
        for (idx, &value) in outputs.iter().enumerate() {
            if value > self.confidence_threshold {
                if let Some(concept) = self.neural_to_symbolic.get(&idx) {
                    let fact = Fact::new(concept.clone(), vec![format!("{:.2}", value)]);
                    facts.push(fact.clone());
                    self.symbolic.add_fact(fact);
                }
            }
        }

        facts
    }

    /// 符号推理
    pub fn reason(&mut self, max_iterations: usize) -> usize {
        self.symbolic.forward_chain(max_iterations)
    }

    /// 目标驱动推理
    pub fn reason_toward_goal(&mut self, goal: &Fact) -> bool {
        self.symbolic.backward_chain(goal)
    }

    /// 完整的感知-推理流程
    pub fn perceive_and_reason(&mut self, inputs: &[f64], max_iterations: usize) -> Vec<Fact> {
        // 1. 神经感知
        let perceived_facts = self.perceive(inputs);
        
        println!("\n=== 感知阶段 ===");
        for fact in &perceived_facts {
            println!("感知到: {}", fact);
        }

        // 2. 符号推理
        println!("\n=== 推理阶段 ===");
        let new_facts = self.reason(max_iterations);
        println!("推导出 {} 个新事实", new_facts);

        // 3. 返回所有事实
        self.symbolic.get_facts().iter().map(|&f| f.clone()).collect()
    }

    /// 训练神经部分
    pub fn train_neural(
        &mut self,
        dataset: &[(Vec<f64>, Vec<f64>)],
        learning_rate: f64,
        epochs: usize,
    ) -> Vec<f64> {
        println!("\n=== 训练神经网络 ===");
        self.neural.train_batch(dataset, learning_rate, epochs)
    }

    /// 添加符号规则
    pub fn add_rule(&mut self, rule: Rule) {
        self.symbolic.add_rule(rule);
    }

    /// 添加符号事实
    pub fn add_fact(&mut self, fact: Fact) {
        self.symbolic.add_fact(fact);
    }

    /// 查询事实
    pub fn query(&self, predicate: &str) -> Vec<&Fact> {
        self.symbolic.query(predicate)
    }

    /// 获取推理日志
    pub fn get_inference_log(&self) -> &[String] {
        self.symbolic.get_inference_log()
    }

    /// 显示推理过程
    pub fn show_inference_log(&self) {
        println!("\n=== 推理日志 ===");
        for log in self.get_inference_log() {
            println!("{}", log);
        }
    }

    /// 解释决策
    pub fn explain(&self, inputs: &[f64]) -> String {
        let mut explanation = String::new();
        
        explanation.push_str("=== 决策解释 ===\n\n");
        explanation.push_str(&format!("输入: {:?}\n\n", inputs));

        // 显示当前所有事实
        explanation.push_str("已知事实:\n");
        for fact in self.symbolic.get_facts() {
            explanation.push_str(&format!("  - {}\n", fact));
        }

        // 显示推理过程
        explanation.push_str("\n推理过程:\n");
        for log in self.get_inference_log() {
            explanation.push_str(&format!("  {}\n", log));
        }

        explanation
    }

    /// 获取神经网络引用
    pub fn neural(&mut self) -> &mut NeuralNetwork {
        &mut self.neural
    }

    /// 获取符号引擎引用
    pub fn symbolic(&mut self) -> &mut SymbolicEngine {
        &mut self.symbolic
    }

    /// 获取Transformer引用
    pub fn transformer(&mut self) -> Option<&mut Transformer> {
        self.transformer.as_mut()
    }

    /// 使用Transformer处理序列并转换为符号
    pub fn process_sequence(&mut self, sequence: &[Vec<f64>]) -> Vec<Fact> {
        if let Some(transformer) = &self.transformer {
            let output = transformer.forward(sequence);
            
            // 将Transformer输出转换为符号事实
            let mut facts = Vec::new();
            for (idx, embedding) in output.iter().enumerate() {
                // 计算平均激活强度
                let avg_activation: f64 = embedding.iter().sum::<f64>() / embedding.len() as f64;
                
                if avg_activation.abs() > self.confidence_threshold {
                    let fact = Fact::new(
                        format!("sequence_feature_{}", idx),
                        vec![format!("{:.3}", avg_activation)],
                    );
                    facts.push(fact.clone());
                    self.symbolic.add_fact(fact);
                }
            }
            facts
        } else {
            Vec::new()
        }
    }

    /// 端到端处理：序列 -> Transformer -> 符号推理
    pub fn understand_and_reason(
        &mut self,
        sequence: &[Vec<f64>],
        max_iterations: usize,
    ) -> Vec<Fact> {
        println!("\n=== Transformer理解阶段 ===");
        let perceived = self.process_sequence(sequence);
        println!("从序列中提取 {} 个特征", perceived.len());

        println!("\n=== 符号推理阶段 ===");
        let new_facts = self.reason(max_iterations);
        println!("推导出 {} 个新事实", new_facts);

        self.symbolic.get_facts().iter().map(|&f| f.clone()).collect()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::neural::{Activation, Layer};

    #[test]
    fn test_neurosymbolic_integration() {
        // 创建简单的神经网络
        let mut nn = NeuralNetwork::new();
        nn.add_layer(Layer::new(2, 3, Activation::ReLU));
        nn.add_layer(Layer::new(3, 2, Activation::Sigmoid));

        // 训练一下以确保有合理的输出
        let training_data = vec![
            (vec![0.9, 0.8], vec![1.0, 1.0]),
        ];
        nn.train_batch(&training_data, 0.1, 50);

        // 创建符号引擎
        let symbolic = SymbolicEngine::new();

        // 创建神经符号系统
        let mut system = NeuroSymbolicSystem::new(nn, symbolic);
        system.set_neural_mapping(0, "hot".to_string());
        system.set_neural_mapping(1, "sunny".to_string());
        system.set_confidence_threshold(0.3); // 降低阈值以确保能检测到

        // 添加规则
        system.add_rule(Rule::new(
            "weather_rule",
            vec![
                Fact::new("hot", vec!["high".to_string()]),
                Fact::new("sunny", vec!["high".to_string()]),
            ],
            Fact::new("good_weather", vec!["true".to_string()]),
            0.9,
        ));

        // 测试感知和推理
        let inputs = vec![0.9, 0.8];
        let facts = system.perceive_and_reason(&inputs, 5);
        
        // 至少应该有一些事实被识别出来
        assert!(!facts.is_empty(), "应该识别出至少一个事实");
    }
}

